#include "laurin-capture-interface.h"
#include <string.h> // for memset


LaurinCaptureInterface::LaurinCaptureInterface(const Glib::ustring& ifaceName)
{
	_cIfaceName = Glib::ustring(ifaceName);
	_context = NULL;
	_datalayer = -1;
}


LaurinCaptureInterface::~LaurinCaptureInterface()
{
	closeCaptureContext();
}


void LaurinCaptureInterface::openCaptureContext()
{
	//TODO: error handling
	char errbuf[PCAP_ERRBUF_SIZE];
	memset(errbuf, 0, PCAP_ERRBUF_SIZE);

	if((_context = pcap_create(_cIfaceName.c_str(), errbuf)) == NULL)
		return;

	if(!setCaptureOptions())
	{
		closeCaptureContext();
		return ;
	}

	pcap_activate(_context);

 	_datalayer = pcap_datalink(_context);
}


void LaurinCaptureInterface::closeCaptureContext()
{
	if(_context != NULL)
		pcap_close(_context);

	_context = NULL;
}


pcap_t* LaurinCaptureInterface::getCaptureContext() const
{
	return _context;
}


bool LaurinCaptureInterface::setCaptureFilter(const Glib::ustring& filterSTM, int subnetMask)
{
	if(isCaptureContextOpen())
	{
		struct bpf_program filter;	   // the bsd packet filter statement

		//set for optimizations
		if(pcap_compile(_context, &filter, filterSTM.c_str(), 1, subnetMask) == -1)
			return false;


		if(pcap_setfilter(_context, &filter) == -1)
			return false;

		pcap_freecode(&filter);

		return true;
	}

	return false;


}


bool LaurinCaptureInterface::setCaptureOptions()
{
	// note that pcap_setdirection doesn't work
	pcap_set_timeout(_context, 1000);
	return true;
}


bool LaurinCaptureInterface::isCaptureContextOpen() const
{
	return _context != NULL;
}


int LaurinCaptureInterface::getDataLayerLink() const
{
	return _datalayer;
}
